package se.webbzon.boltzmann.game.sequence;

import se.webbzon.oschi01.worldobject.WorldObject;

public abstract class SequenceNode {
	
	// Whatever the sequence node is busy or not
	private boolean busy;
	
	// The sequence associated with this sequence node
	private final Sequence sequence;
	
	/*============================================================
	Constructors
	============================================================*/
	
	public SequenceNode(Sequence sequence) {
		this.sequence = sequence;
	}
	
	/*============================================================
	Public Methods
	============================================================*/
	
	/** Returns the number of branches of this sequence node. **/
	public abstract int branches();
	
	/** Returns the (n+1):th branch of this sequence node. **/
	public abstract SequenceNode getBranch(int n);
	
	/** Returns true if this node is a leaf. **/
	public final boolean isLeaf() {
		return branches() == 0;
	}
	
	/** Returns true if the sequence node was triggered. If the 
	 * sequence node is already busy then false is returned. This
	 * method should only be called from a sequence. **/
	public final boolean begin() {
		if (busy)
			return false;
		else {
			busy = true;
			onBegin(sequence.getBinding(this));
			return true;
		}
	}
	
	/** Returns true if the sequence node was ended. If the sequence
	 * node has not been triggered then false is returned. This method
	 * should only be called from a sequence. **/
	public final boolean end() {
		if (busy) {
			busy = false;
			onEnd(sequence.getBinding(this));
			return true;
		} else
			return false;
	}
	
	/** Returns the sequence associated with this sequence node. **/
	public Sequence getSequence() {
		return sequence;
	}
	
	/*============================================================
	Protected Methods
	============================================================*/
	
	/** This method is invoked when the sequence node is triggered. **/
	protected abstract void onBegin(WorldObject binding);
	
	/** This method is invoked when the sequence node is ended. **/
	protected abstract void onEnd(WorldObject binding);

}
